package com.wpml;

import java.io.*;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.util.*;

/**
 * @Description
 * @Date 2021-08-12
 * @Author wangpei
 **/
public class GeneratorMain {

    static String url = "jdbc:mysql://8.141.50.71:3306/msb_uc";
    static String username = "root";
    static String password = "root";

    static String projectName = "wpml-generator";
    static String javaPath = "src\\main\\java";
    static String packageName = "";
    static String rootPkg = "";
    static boolean useLombok = false;

    static Properties properties;

    static {
        try {
            InputStream inputStream = ClassLoader.getSystemResourceAsStream("application.properties");
            properties = new Properties();
            properties.load(inputStream);
            projectName = properties.getProperty("projectName");
            javaPath = properties.getProperty("javaPath");
            packageName = properties.getProperty("packageName");
            rootPkg = properties.getProperty("rootPkg");
            useLombok = Boolean.valueOf(properties.getProperty("useLombok"));
            System.out.println(String.format("projectName = %s, javaPath = %s, ", projectName, javaPath));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception{
        Class.forName("com.mysql.jdbc.Driver");

        Connection connection = DriverManager.getConnection(url, username, password);

        DatabaseMetaData metaData = connection.getMetaData();

        ResultSet tables = metaData.getTables("msb_uc", null, "uc_user", null);

        while (tables.next()) {
            StringJoiner contentBuilder = new StringJoiner("\n");
            contentBuilder.add(rootPkg + "\n");

            String table_name = tables.getString("TABLE_NAME");

            ResultSet columns = metaData.getColumns("msb_uc", null, table_name, null);

            Map<String, ColumnProperty> dataMap = new LinkedHashMap<>();
            while (columns.next()) {
                String colName = columns.getString("COLUMN_NAME"); // 字段名
                String colType = columns.getString("TYPE_NAME"); // 字段属性
                String colRemark = columns.getString("REMARKS"); // 字段备注
//                System.out.println(String.format("%s\t%s\t%s", colName, colType, colRemark));

                dataMap.put(colName, new ColumnProperty(colName, colType, colRemark));
            }


            if (useLombok) {
                contentBuilder.add("import lombok.Data;\nimport lombok.ToString;\nimport lombok.experimental.Accessors;\n");
            }

            for (Map.Entry<String, ColumnProperty> entry : dataMap.entrySet()) {
                String pkg = Utils.IMPORT_PACKAGE_MAP.get(entry.getValue().colType);
                if (pkg != null) {
                    contentBuilder.add(pkg);
                }
            }

            if (useLombok) {
                contentBuilder.add("\n@Data\n@ToString\n@Accessors");
            }
            contentBuilder.add("public class " + Utils.generatorClassName(table_name) + " {");

            for (Map.Entry<String, ColumnProperty> entry : dataMap.entrySet()) {

                String javaType = Utils.SQL_TYPE_2_JAVA_TYPE_MAP.get(entry.getValue().colType);
                contentBuilder.add("\tprivate " + javaType + " " + Utils.generatorFieldName(entry.getKey()) + ";\n");
            }

            contentBuilder.add("}");
//            System.out.println("contentBuilder -->> " + contentBuilder.toString());

            Utils.createFile(packageName, Utils.generatorClassName(table_name), contentBuilder.toString());

        }


    }

    static class Utils{
        public final static Map<String, String> SQL_TYPE_2_JAVA_TYPE_MAP = new HashMap<>();

        public final static Map<String, String> IMPORT_PACKAGE_MAP = new HashMap<>();

        static {
            SQL_TYPE_2_JAVA_TYPE_MAP.put("BIGINT", "Long");
            SQL_TYPE_2_JAVA_TYPE_MAP.put("VARCHAR", "String");
            SQL_TYPE_2_JAVA_TYPE_MAP.put("TEXT", "String");
            SQL_TYPE_2_JAVA_TYPE_MAP.put("INT", "Integer");
            SQL_TYPE_2_JAVA_TYPE_MAP.put("BIGINT UNSIGNED", "Long");
            SQL_TYPE_2_JAVA_TYPE_MAP.put("TINYINT UNSIGNED", "Byte");
            SQL_TYPE_2_JAVA_TYPE_MAP.put("TINYINT", "Byte");
            SQL_TYPE_2_JAVA_TYPE_MAP.put("DECIMAL", "BigDecimal"); // import java.math.BigDecimal;


            IMPORT_PACKAGE_MAP.put("DECIMAL", "import java.math.BigDecimal;"); // import java.math.BigDecimal;
        }


        public static void createFile(String packageName, String fileName, String content) {
            try {
                String rootPath = createPkg(packageName);
                rootPath += File.separator + fileName + ".java";

                File file = new File(rootPath);
                FileOutputStream fos = new FileOutputStream(file);
                fos.write(content.getBytes());
                if (!file.exists()) {
                    file.createNewFile();
                }
                fos.close();
                System.out.println("文件创建成功");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        /**
         * 创建包
         * @param packageName 包名
         * @return
         */
        public static String createPkg(String packageName) {
            String rootPath = System.getProperty("user.dir");
            if (!rootPath.contains(projectName)) {
                rootPath += File.separator + projectName;
            }

            rootPath += File.separator + javaPath;

            String[] pkg = packageName.split("\\.");
            for (String name : pkg) {
                rootPath += File.separator + name;
            }

            File file = new File(rootPath);
            if (!file.exists()) {
                file.mkdirs();
            }
            return rootPath;
        }

        public static String generatorClassName(String tbName) {
            String[] tn = tbName.split("_");
            StringBuilder clazzName = new StringBuilder();
            for (String s : tn) {
                clazzName.append(s.substring(0, 1).toUpperCase()).append(s.substring(1));
            }
            return clazzName.toString();
        }

        public static String generatorFieldName(String columnName) {
            String[] cn = columnName.split("_");
            StringBuilder fieldName = new StringBuilder();
            for (int i = 0; i < cn.length; i++) {
                if (i == 0) {
                    fieldName.append(cn[i].substring(0, 1).toLowerCase()).append(cn[i].substring(1));
                } else {
                    fieldName.append(cn[i].substring(0, 1).toUpperCase()).append(cn[i].substring(1));
                }
            }
            return fieldName.toString();
        }
    }

    static class ColumnProperty {
        String colName;
        String colType;
        String colRemark;

        public ColumnProperty(String colName, String colType, String colRemark) {
            this.colName = colName;
            this.colType = colType;
            this.colRemark = colRemark;
        }

        public String getColName() {
            return colName;
        }

        public void setColName(String colName) {
            this.colName = colName;
        }

        public String getColType() {
            return colType;
        }

        public void setColType(String colType) {
            this.colType = colType;
        }

        public String getColRemark() {
            return colRemark;
        }

        public void setColRemark(String colRemark) {
            this.colRemark = colRemark;
        }
    }
}


